<template>
  <px-dialog
    v-model="dialogShow"
    title="数据分析"
    width="600px"
    style="min-height: 580px"
    destroy-on-close
    align-center
    :append-to-body="true"
    @closed="dialogClosed"
  >
    <div class="w-[100%] h-[100%] pt-[5px]">
      <px-date-picker
        v-model="dataSelect"
        type="datetime"
        range-separator="至"
        start-placeholder="选择时间"
        :disabled-date="disabledDate"
        value-format="YYYY-MM-DD HH:mm:ss"
        format="YYYY-MM-DD HH:mm:ss"
        @change="dateChange"
      />

      <!-- <px-button-group class="mt-[5px] mb-[5px]">
        <px-button type="primary" @click="timeRadioChange('now')">最近一小时</px-button>
        <px-button type="primary" @click="timeRadioChange('pre')">上一小时</px-button>
        <px-button type="primary" :disabled="nextTimeBtnDisable" @click="timeRadioChange('next')">下一小时</px-button>
        <px-switch v-model="switchVal" size="large" active-text="对比" inactive-text="单选" @change="switchChange" />
      </px-button-group> -->
      <div class="days-select">
        <px-scrollbar max-height="280px" always>
          <px-check-tag
            v-for="item in contentList"
            :key="item.positionNum"
            :checked="selected.includes(item.positionNum)"
            class="mb-2 mr-1"
            @change="toggleDay(item.positionNum)"
          >
            {{ item.attributeName }}
          </px-check-tag>
        </px-scrollbar>
      </div>
      <div ref="echartRef" />
    </div>
  </px-dialog>
</template>

<script lang="ts" setup>
import { computed, markRaw, nextTick, onMounted, ref, watch } from "vue";
import * as echarts from "echarts";
import { eqpTagLineChart } from "@/api/visual/visualConfig";
import dayjs from "dayjs";
import { queryByGroupEqpIds } from "@/api/visual/visualConfig";
const WIDHT = 500;
const HEIGHT = 500;
const isShow = defineModel("isShow");
const dialogShow = ref(false);
const props = withDefaults(
  defineProps<{
    eqpId: string;
  }>(),
  { eqpId: "" }
);
const echartRef = ref();
let echartInstance: echarts.ECharts;
const contentList = ref([]);
const dataSelect = ref("");
const switchVal = ref(false);
let option: Partial<{
  grid: Record<string, any>;
  legend: Record<string, any>;
  xAxis: Record<string, any>;
  yAxis: Record<string, any>;
  series: any[];
  toolbox: Record<string, any>;
  tooltip: Record<string, any>;
}> = {
  tooltip: {
    trigger: "axis",
    axisPointer: {
      type: "cross",
      label: {
        backgroundColor: "#6a7985"
      }
    }
  },
  legend: {
    data: [],
    icon: "rect", // 设置图例图标为小长方形
    itemWidth: 12.5, // 将图例图标的宽度设置为默认值的一半
    itemHeight: 4 // 将图例图标的高度设置为默认值的一半
  },
  xAxis: {
    type: "category",
    boundaryGap: false
  },
  yAxis: [],
  series: []
};
let yaxiMap: any[];
let seriesArr: any[];

const selected = ref([]);

const nextTimeBtnDisable = computed(() => {
  return judgeTime(dataSelect.value);
});

function dialogClosed() {
  isShow.value = false;
  dialogShow.value = false;
  selected.value = [];
  contentList.value = [];
}
watch(
  () => isShow.value,
  async newVal => {
    if (newVal) {
      dialogShow.value = true;
      contentList.value = await getTagsById();

      nextTick(() => {
        let [endTime, startTime] = getTimeRange();
        dataSelect.value = endTime;
        echartInstance = markRaw(
          echarts.init(echartRef.value, undefined, {
            width: WIDHT,
            height: HEIGHT
          })
        );

        if (contentList.value.length > 0) {
          toggleDay(contentList.value[0].positionNum);
        }
      });
    } else {
      dialogClosed();
    }
  }
);

async function getTagsById() {
  return queryByGroupEqpIds({ eqpId: props.eqpId });
}
//真实渲染数据处理数据
function rednerRealChart() {
  if (echartInstance && echartInstance.resize) {
    echartInstance.resize({
      width: WIDHT,
      height: HEIGHT
    });

    let emptyOption = {
      title: {
        text: "暂无数据",
        x: "center",
        y: "center",
        textStyle: {
          color: "#8693B0",
          fontWeight: "normal",
          fontSize: 16
        }
      }
    };

    // 配置参数
    echartInstance.clear();
    if (option.series.length > 0) echartInstance.setOption(option, true);
    else echartInstance.setOption(emptyOption, true);
    console.log(option);
  }
}
function dateChange() {
  renderChart(contentList.value);
}
const disabledDate = (time: Date) => {
  const currentTime = new Date();
  return time.getTime() > currentTime.getTime();
};
function getHourBefore(dateTimeStr, hours = 24) {
  const dateTime = dayjs(dateTimeStr, "YYYY-MM-DD HH:mm:ss");
  const oneHourBefore = dateTime.subtract(hours, "hour");
  return oneHourBefore.format("YYYY-MM-DD HH:mm:ss");
}
// 新增，解决坐标轴文字太长重叠的问题，兼容value值无空格场景，默认步长为4
function isValidDateTimeFormat(dateTimeString) {
  // 正则表达式匹配 YYYY-MM-DD HH:mm:ss 格式
  const regex = /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/;

  // 执行匹配
  return regex.test(dateTimeString);
}
function extractTimeFromDateTimeString(dateString) {
  // 正则表达式匹配 YYYY-MM-DD HH:mm:ss 格式
  const regex = /^(\d{4}-\d{2}-\d{2}) (\d{2}:\d{2}:\d{2})$/;
  // 执行匹配
  const match = dateString.match(regex);

  // 如果匹配成功，返回时间部分
  if (match && match[2]) {
    return match[2]; // HH:mm:ss
  }

  // 如果没有匹配成功，返回null或抛出错误
  return dateString;
}
//数据初始化加接口请求
async function renderChart(newVal = []) {
  if (!newVal) return;

  option.toolbox = {
    feature: {
      saveAsImage: {
        title: "导出图片"
      }, // 导出图片
      dataZoom: {
        title: {
          zoom: "放大",
          back: "还原"
        }
      } // 数据区域缩放
    }
  };
  let data = deepCopy(newVal);
  let legendData = deepCopy(selected.value);

  // let positionNums = data.reduce((acc, cur) => {
  //   if (legendData.find(name => cur.title === name)) {
  //     acc.push(cur.positionNum);
  //   }
  //   return acc;
  // }, []);

  let [endTime, startTime] = getTimeRange();
  if (dataSelect.value && dataSelect.value !== "") {
    endTime = dataSelect.value;
    startTime = getHourBefore(endTime);
  } else {
    dataSelect.value = endTime;
  }

  let rawData = { xaxisList: [], yaxis: [] };
  if (legendData.length > 0) {
    rawData = await eqpTagLineChart({ tagNums: legendData, startTime, endTime });
  } else {
    echartInstance?.clear();
    return;
  }
  let { xaxisList, yaxis } = rawData;
  yaxis = yaxis?.filter(item => !!item.name);
  // let selectedYaxis = yaxis.reduce((acc, cur) => {
  //   if (legendData.find(name => cur.name === name)) {
  //     acc.push(cur);
  //   }
  //   return acc;
  // }, []);
  // console.log(selectedYaxis);
  try {
    option.grid = {
      // top: "20%",
      // bottom: "20%"
      top: "20%",
      bottom: 0,
      left: "2%",
      right: "5%",
      containLabel: true
    }; // 新增，解决折线图空白区域过多的问题，containLabel:true,宽高包含label
    // option.legend.data = legendData;
    // option.legend.orient = "vertical";
    // option.legend.orient = "0%";
    if (!legendData || legendData.length === 0) return;

    // option.xAxis.data = deepCopy(xaxis);
    delete option.xAxis.data;
    option.xAxis.type = "time";

    option.xAxis.splitNumber = 4;
    // option.xAxis.axisLabel = {
    //   // interval: 13,
    //   formatter: value => formatter(value)
    // };
    yaxiMap = yaxis.map((item, index) => {
      const { name, unit } = item;
      const SPLIT_NUM = 7;
      let max = getMax(Number(Math.max(...yaxis[index].data) || 100), SPLIT_NUM);
      let distance = max / SPLIT_NUM;
      return {
        type: "value",
        name: `${name}(${unit})`,
        show: index > 1 ? false : true,
        position: index === 0 ? "left" : "right",
        max: max,
        min: 0,
        interval: distance,
        splitNumber: SPLIT_NUM,
        nameRotate: index === 0 ? 0.01 : -0.01 // 新增，解决y轴name过长，文字截断显示不全的问题
      };
    });
    option.yAxis = deepCopy(yaxiMap);
    seriesArr = yaxis.map((item, index) => {
      const { name, data } = item;
      let newData = mergeArrays(xaxisList[index], data);

      return {
        name,
        type: "line",
        symbol: "react",
        yAxisIndex: index,
        data: newData,
        connectNulls: true
      };
    });
    option.series = deepCopy(seriesArr);
    rednerRealChart();
    // 更新大小
  } catch (e) {
    console.error(e);
  }
}
async function switchChange(val) {
  if (!val) {
    if (selected.value.length >= 2) {
      selected.value = [selected.value[0]];
      await renderChart(contentList.value);
    }
  }
}

function getMax(num1, num2) {
  if (!num1 || !num2) {
    return 0;
  }
  num1 = Math.ceil(num1);
  num2 = Math.ceil(num2);

  if (num1 % num2 === 0) {
    return num1;
  }
  for (let i = num1; ; i++) {
    if (i % num2 === 0) {
      return i;
    }
  }
}

function getTimeRange(hours = 24) {
  const currentTime = dayjs().format("YYYY-MM-DD HH:mm:ss");
  const pastTime = dayjs().subtract(hours, "hour").format("YYYY-MM-DD HH:mm:ss");
  return [currentTime, pastTime];
}
function deepCopy(data) {
  try {
    return JSON.parse(JSON.stringify(data));
  } catch (error) {
    console.error(error);
    return {};
  }
}
function getAdjustedTime(inputTime) {
  const inputTimeFormatted = dayjs(inputTime).format("YYYY-MM-DD HH:mm:ss");
  const inputTimePlusOneHour = dayjs(inputTimeFormatted).add(1, "hour").format("YYYY-MM-DD HH:mm:ss");
  const currentTimeFormatted = dayjs().format("YYYY-MM-DD HH:mm:ss");
  return dayjs(currentTimeFormatted).isAfter(dayjs(inputTimePlusOneHour)) ? inputTimePlusOneHour : currentTimeFormatted;
}
function judgeTime(inputTime) {
  if (dayjs().isBefore(dayjs(inputTime))) return true;
  if (dayjs().diff(inputTime, "minute") < 1) return true;
  return false;
}

function timeRadioChange(val) {
  if (!dataSelect.value) return;
  if (val === "now") {
    dataSelect.value = dayjs().format("YYYY-MM-DD HH:mm:ss");
    // nextTimeBtnDisable.value = true;
  } else if (val === "pre") {
    dataSelect.value = getHourBefore(dataSelect.value);
    // nextTimeBtnDisable.value = false;
  } else {
    dataSelect.value = getAdjustedTime(dataSelect.value);
  }
  dateChange();
}
const toggleDay = async val => {
  if (selected.value.includes(val)) {
    selected.value = selected.value.filter(v => v !== val);
  } else {
    if (switchVal.value) {
      if (selected.value.length >= 2) {
        selected.value.shift();
      }
      selected.value.push(val);
    } else {
      selected.value = [val];
    }
  }
  await renderChart(contentList.value);
};
function mergeArrays(arr1, arr2) {
  const maxLength = Math.max(arr1.length, arr2.length); // 获取两个数组的最大长度
  const result = [];

  for (let i = 0; i < maxLength; i++) {
    result.push([arr1[i] !== undefined ? arr1[i] : null, arr2[i] !== undefined ? arr2[i] : null]);
  }

  return result;
}
</script>

<style lang="scss" scoped>
.days-select {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  width: 100%;
  margin-top: 15px;
  margin-bottom: 15px;
}

.actions {
  display: flex;
  gap: 10px;
}
</style>
